package com.csair.platform.cit.service.timer.enterprise;

import java.util.Date;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.csair.invoice.common.base.util.JAXBUtil;
import com.csair.invoice.common.base.vo.JsonResult;
import com.csair.platform.cit.facade.exception.CitBizException;
import com.csair.platform.cit.facade.model.xml.DeclareXml;
import com.csair.platform.cit.service.cache.RedisUtil;
import com.csair.platform.cit.service.dao.CitDeclareRecordRepository;
import com.csair.platform.cit.service.entity.CitDeclareRecord;
import com.csair.platform.cit.service.feignclient.sbcenter.GdTaxUserClient;
import com.csair.platform.gts.sdk.EnterpriseResultClient;
import com.csair.platform.gts.sdk.model.Header;
import com.csair.platform.sbcenter.facade.model.login.GdTaxUserInfo;

import lombok.extern.slf4j.Slf4j;

/**
 * 获取企业所得税申报结果-定时任务
 * @author zhengxincheng
 */
@Slf4j
@Configuration
@EnableScheduling
public class EnterpriseResultScheduleTask {
    @Value("${dzswj.url}")
    private String serverUrl;

    @Value("${timer.enterpriseResult}")
    private Boolean flag;

    @Autowired
    private GdTaxUserClient gdTaxUserFeignClient;

	/**
	 * 企业所得税申报进度dao
	 */
	@Autowired
	protected CitDeclareRecordRepository cdrr;
	
    @Autowired
    private RedisUtil redisUtil;

    public final static String ENTERPRISE_RESULT_TYPE = "enterpriseResult";

    public static final String SUCCESS = "0";
    public static final String FAIL = "-1";

    @Scheduled(cron = "0/60 * * * * ? ")
    public void enterpriseResultTask() throws Exception {
        if(!flag){
            return;
        }
        try {
        	List<CitDeclareRecord> declareRecors = cdrr.findCitDeclareRecordByStatus();
            if (CollectionUtils.isEmpty(declareRecors)) {
                return;
            }
            CitDeclareRecord declareRecord = declareRecors.get(0);      
            String jylsh = declareRecord.getJylsh();
            log.info("查询申报结果：有" + declareRecors.size() +"条任务待查询，先查询第一条, 交易流水号：" + jylsh);
            
            //1.先登录电子税务局，获取sessionid
            JsonResult<GdTaxUserInfo> user =  gdTaxUserFeignClient.autoLogin(declareRecord.getNsrsbh(), "772352");
            String sessionId = user.getData().get(0).getSsoSessionId();

            //2.发送报文
            EnterpriseResultClient client = new EnterpriseResultClient(serverUrl);
            Header header = new Header();
            header.setSessionId(sessionId);
            header.setNsrsbh(declareRecord.getNsrsbh());
            String result = client.query(header, jylsh);
            log.info("税局返回结果：" + result);
            
            //3.解析报文
            //返回报文信息
            //申报失败样例 {"head":{"errorCode":"0","timestamp":1632710881731,"time":0,"gtime":67},"body":"{\"msg\":\"主表第20行[总机构具有主体生产经营职能的部门分摊所得税额]【80542.45】应等于A202000表分支机构情况[独立生产经营部门 的分配税额]【51334.84】\\n[资产总额（万元）]填报的单位是万元且必须大于0，且保留两位小数！\\n[资产总额（万元）]填报的单位是万元且必须大于0，且保留两位小数！\\n分支机构本期分摊比例【2500.00000000%】不能大于100%！\\n[季末从业人数]必须大于0且为整数！\\n[季初从业人数]必须大于0且为整数！\\n\",\"code\":\"0\",\"sbzt\":\"9\"}"}
            //申报进行中样例 {"head":{"errorCode":"0","timestamp":1632884160465,"time":0,"gtime":2635},"body":"{\"msg\":\"系统正在进行申报。\",\"code\":\"0\",\"sbzt\":\"0\"}"}
            //申报成功样例  {"head":{"errorCode":"0","timestamp":1632902935381,"time":0,"gtime":80},"body":"{\"msg\":\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?><taxML xsi:type=\\\"HXZGSB10868Response\\\" xmlns=\\\"http://www.chinatax.gov.cn/dataspec/\\\" xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\"><svRet><pzxh>10014421000118820265</pzxh><ybtse>0.0</ybtse><returnBz>Y</returnBz><ybse>0.0</ybse><ytse>0.0</ytse><sbuuid>32ADFE419935F6366A3F83BABD61E9DE</sbuuid></svRet></taxML>\",\"ysqxxid\":\"30913E4AFFFFDB6227811054A40A24AF\",\"code\":\"0\",\"sbzt\":\"1\",\"yzpzxh\":\"10014421000118820265\"}"}
            JSONObject head = JSON.parseObject(result).getJSONObject("head");
            String headErrorCode = head.getString("errorCode");
            if (!"0".equals(headErrorCode)) {
           	   throw new CitBizException(6066, "查询申报结果，网关报错").print();
            }
            JSONObject json = JSONObject.parseObject(result);
            String body = json.getString("body");
            JSONObject bodyJson = JSONObject.parseObject(body);
            String code = bodyJson.getString("code");
            String sbzt = bodyJson.getString("sbzt");
            String msg = bodyJson.getString("msg");
            if(SUCCESS.equals(code)){
    	    	if ("1".equals(sbzt)) { //申报状态： 0-处理中，1-成功, 9-失败
    		    	declareRecord.setStatus("申报成功");
    		    	declareRecord.setJgfkxx("申报成功");
    		    	declareRecord.setSbsj(new Date()); //申报成功时间
    		    	//拿到的msg是一个xml
    		    	DeclareXml updateData = parseXml(msg);
    		    	declareRecord.setPzxh(updateData == null ? "" : updateData.getPzxh());
    		    	declareRecord.setSbse(updateData == null ? "" : updateData.getYbtse());
    	    	} else if ("9".equals(sbzt)) {
    		    	declareRecord.setStatus("申报失败");
    		    	declareRecord.setJgfkxx(msg);
    	    	} 
            } else {
    	    	declareRecord.setStatus("申报失败");
            }
            declareRecord.setFkdm(sbzt);
	    	declareRecord.setUpdateTime(new Date());
            cdrr.save(declareRecord);
    	    log.info("企业所得税申报受理记录更新成功");
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            redisUtil.delete(ENTERPRISE_RESULT_TYPE);
        }
    }
    
    /**
     * 解析xml为vo
     * @param bodyXml xml
     * @return vo 
     * @throws DocumentException xml文档异常
     */
    @SuppressWarnings("unchecked")
	private DeclareXml parseXml(String bodyXml) throws DocumentException {
   	 	Document document = DocumentHelper.parseText(bodyXml);
   	 	log.info("xml是：" + bodyXml);
        Element root = document.getRootElement();
        List<Element> childElements = root.elements();
        String sbfk = childElements.get(0).asXML();
        DeclareXml declareXml = (DeclareXml) JAXBUtil.xmlToObj(sbfk, DeclareXml.class);
        return declareXml;
   }
}
